﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using sabConn;
using System.Xml;
using System.Reflection;

namespace TestForm
{
    public partial class frmMain : Form
    {
        #region controls
        CheckBox chkPercentage = new CheckBox();
        CheckBox chkIndex = new CheckBox();
        CheckBox chkFilename = new CheckBox();
        CheckBox chkPriority = new CheckBox();
        CheckBox chkAge = new CheckBox();
        CheckBox chkTimeLeft = new CheckBox();
        CheckBox chkMb = new CheckBox();
        CheckBox chkMbLeft = new CheckBox();
        CheckBox chkStatus = new CheckBox();
        CheckBox chkCategory = new CheckBox();
        CheckBox chkNzoID = new CheckBox();

        CheckBox chkhID = new CheckBox();
        CheckBox chkhName = new CheckBox();
        CheckBox chkhSizeBytes = new CheckBox();
        CheckBox chkhCategory = new CheckBox();
        CheckBox chkhDownloadTime = new CheckBox();
        CheckBox chkhPath = new CheckBox();
        CheckBox chkhPostprocTime = new CheckBox();
        CheckBox chkhUrl = new CheckBox();
        CheckBox chkhUrlInfo = new CheckBox();
        CheckBox chkhActionLine = new CheckBox();
        CheckBox chkhNzbNam = new CheckBox();
        #endregion controls

        #region variables
        public XmlDocument settings;
        public sabConn.ServerConnection sabCom;
        public Queue sabqueue;
        private BindingSource jobSource = new BindingSource();
        private BindingSource hcatSource = new BindingSource();
        private BindingSource qcatSource = new BindingSource();
        private BindingSource historySource = new BindingSource();
        private BindingList<HistoryJob> masterHistoryList = new BindingList<HistoryJob>();
        private BindingList<Job> masterJobList = new BindingList<Job>();
        private BindingList<string> b_cats = new BindingList<string>();
        private BindingList<Job> filteredJobList;
        private BindingList<HistoryJob> filteredHistoryList;
        private bool dgvqueue_forcerefresh = false;
        private string curHistoryFilter, curQueueFilter;
        private bool queueIsFiltered, historyIsFiltered;
        private bool dgvQueueFormatted = false;
        private bool dgvHistoryFormatted = false;
        #endregion variables

        public frmMain()
        {
            InitializeComponent();
        }

        #region EventHandlers

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.apikey != String.Empty &&
                Properties.Settings.Default.server != String.Empty &&
                Properties.Settings.Default.port != String.Empty)
            {
                try
                {

                    if (sabCom.server == "")
                    {
                        sabCom = new ServerConnection(Properties.Settings.Default.server, Properties.Settings.Default.port,
                        Properties.Settings.Default.apikey, Properties.Settings.Default.username, Properties.Settings.Default.password,
                        Properties.Settings.Default.refreshrate);
                    }
                }
                catch
                {
                    sabCom = new ServerConnection(Properties.Settings.Default.server, Properties.Settings.Default.port,
                        Properties.Settings.Default.apikey, Properties.Settings.Default.username, Properties.Settings.Default.password,
                        Properties.Settings.Default.refreshrate);
                }
                //Fire update on another thread
                if (bgUpdateThread.IsBusy == false)
                {
                    bgUpdateThread.RunWorkerAsync(sabCom);
                }
            }
        }

        private void tsmiSettings_Click(object sender, EventArgs e)
        {
            frmSettings settingsDialog;
            settingsDialog = new frmSettings(this);
            settingsDialog.Show();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.apikey != String.Empty &&
                Properties.Settings.Default.server != String.Empty &&
                Properties.Settings.Default.port != String.Empty)
            {
                sabCom = new ServerConnection(Properties.Settings.Default.server, Properties.Settings.Default.port,
                    Properties.Settings.Default.apikey, Properties.Settings.Default.username, Properties.Settings.Default.password,
                    Properties.Settings.Default.refreshrate);
                timer1.Interval = (int)sabCom.refreshinterval;
            }
            else
            {
                timer1.Interval = 3000;
            }
            timer1.Start();
            dqvQueue_headerContext_Init();
            dgvHistory_headerContext_Init();
        }

        private void bgUpdateThread_DoWork(object sender, DoWorkEventArgs e)
        {
            ServerConnection sabconn = e.Argument as ServerConnection;
            sabconn.update();
            e.Result = sabconn;
        }

        private void bgUpdateThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //Passes back the ServerConnection with update vars.
            ServerConnection tmpsab = e.Result as ServerConnection;
            this.sabCom = tmpsab;

            //dgvQueue needs information populated prior to reformatting. Hence code located here.
            if (dgvQueueFormatted == false)
            {
                dgvQueue_Init();  //Applies formatting and loads column width. Inits data sources.
            }
            else
            {
                dgvQueue_Update();
            }
            if (dgvHistoryFormatted == false)
            {
                dgvHistory_Init();
                lstviewCat_Init();
            }
            else
            {
                dgvHistory_Update();
            }
            ssStatus_Update();
        }

        #region QueueContextCheckBoxes

        void chkNzoID_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["nzo_id"].Visible = chkNzoID.Checked;
        }

        void chkPercentage_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["percentage"].Visible = chkPercentage.Checked;
        }

        void chkCategory_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["category"].Visible = chkCategory.Checked;
        }

        void chkStatus_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["status"].Visible = chkStatus.Checked;
        }

        void chkMbLeft_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["mbleft"].Visible = chkMbLeft.Checked;
        }

        void chkMb_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["mb"].Visible = chkMb.Checked;
        }

        void chkAge_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["age"].Visible = chkAge.Checked;
        }

        void chkTimeLeft_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["timeleft"].Visible = chkTimeLeft.Checked;
        }

        void chkPriority_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["priority"].Visible = chkPriority.Checked;
        }

        void chkIndex_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["Index"].Visible = chkIndex.Checked;
        }

        void chkFilename_CheckedChanged(object sender, EventArgs e)
        {
            dgvQueue.Columns["Filename"].Visible = chkFilename.Checked;
        }

        #endregion QueueContextCheckBoxes

        #region HistoryContextCheckBoxes
        void chkhID_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["id"].Visible = chkhID.Checked;
        }

        void chkhActionLine_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["action_line"].Visible = chkhActionLine.Checked;
        }

        void chkhCategory_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["category"].Visible = chkhCategory.Checked;
        }

        void chkhDownloadTime_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["download_time"].Visible = chkhDownloadTime.Checked;
        }

        void chkhPath_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["path"].Visible = chkhPath.Checked;
        }

        void chkhName_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["name"].Visible = chkhName.Checked;
        }

        void chkhNzbNam_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["nzb_name"].Visible = chkhNzbNam.Checked;
        }

        void chkhSizeBytes_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["size_byte"].Visible = chkhSizeBytes.Checked;
        }

        void chkhUrl_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["url"].Visible = chkhUrl.Checked;
        }

        void chkhUrlInfo_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["url_info"].Visible = chkhUrlInfo.Checked;
        }

        void chkhPostprocTime_CheckedChanged(object sender, EventArgs e)
        {
            dgvHistory.Columns["postproc_time"].Visible = chkhPostprocTime.Checked;
        }
        #endregion HistoryContextCheckBoxes

        private void dgvQueue_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            //When dgvQueue is populated, _RowEnter is triggered on each row creation
            //Hence we wait until data is populated before applying the row selection code.
            try
            {
                if (dgvQueueFormatted == true)
                {
                    if (dgvQueue.SelectedCells.Count != 0)
                    {
                        DataGridViewCellStyle selected;
                        int tmpindex = e.RowIndex;

                        selected = new DataGridViewCellStyle();
                        selected.BackColor = Color.DarkBlue;
                        selected.ForeColor = Color.White;
                        selected.SelectionBackColor = Color.DarkBlue;
                        selected.SelectionForeColor = Color.White;
                        dgvQueue.Rows[tmpindex].DefaultCellStyle = selected;
                    }
                }
            }
            catch
            {

            }
        }

        private void dgvHistory_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            //When dgvQueue is populated, _RowEnter is triggered on each row creation
            //Hence we wait until data is populated before applying the row selection code.
            try
            {
                if (dgvHistoryFormatted == true)
                {
                    if (dgvHistory.SelectedCells.Count != 0)
                    {
                        DataGridViewCellStyle selected;
                        int tmpindex = e.RowIndex;

                        selected = new DataGridViewCellStyle();
                        selected.BackColor = Color.DarkBlue;
                        selected.ForeColor = Color.White;
                        selected.SelectionBackColor = Color.DarkBlue;
                        selected.SelectionForeColor = Color.White;
                        dgvHistory.Rows[tmpindex].DefaultCellStyle = selected;
                    }
                }
            }
            catch
            {

            }
            //Populate detail grid.
            if (dgvHistoryFormatted == true)
            {
                if (dgvHistory.SelectedCells.Count > 0)
                {
                    try
                    {
                        HistoryJob tmpJob = getHistoryJobById((int)dgvHistory.Rows[dgvHistory.SelectedCells[0].RowIndex].Cells[0].Value);
                        tvStageLog.Nodes.Clear();
                        for (int i = 0; i <= tmpJob.stagelog.stages.Count - 1; i++)
                        {
                            tvStageLog.Nodes.Add(tmpJob.stagelog.stages[i].name);
                            for (int t = 0; t <= tmpJob.stagelog.stages[i].actions.Count - 1; t++)
                            {
                                tvStageLog.Nodes[i].Nodes.Add(tmpJob.stagelog.stages[i].actions[t]);
                            }
                        }
                        tvStageLog.ExpandAll();
                    }
                    catch
                    {
                        tvStageLog.Nodes.Clear();
                    }
                }
            }
        }

        private void dgvHistory_RowLeave(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                DataGridViewCellStyle unselected;
                int tmpindex = e.RowIndex;

                unselected = new DataGridViewCellStyle();
                unselected.BackColor = Color.White;
                unselected.ForeColor = Color.Black;
                dgvHistory.Rows[tmpindex].DefaultCellStyle = unselected;
            }
            catch
            {

            }
        }

        private void dgvQueue_RowLeave(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                DataGridViewCellStyle unselected;
                int tmpindex = e.RowIndex;

                unselected = new DataGridViewCellStyle();
                unselected.BackColor = Color.White;
                unselected.ForeColor = Color.Black;
                dgvQueue.Rows[tmpindex].DefaultCellStyle = unselected;
            }
            catch
            {

            }
        }

        private void dgvQueue_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                cmsColums.Show(System.Windows.Forms.Cursor.Position);
            }
        }

        private void dgvHistory_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                cmsHistoryColums.Show(System.Windows.Forms.Cursor.Position);
            }
        }        

        private void dgvQueue_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            try
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Right)
                {
                    Point pos = this.PointToClient(Cursor.Position);

                    cmsJobRow.Show(this, pos);
                }
            }
            catch
            {
            }
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            dgvQueue_SaveDetails();
            dgvHistory_SaveDetails();
            StringCollection stringCollection = new StringCollection();
            int i = 0;
            foreach (DataGridViewColumn col in dgvHistory.Columns)
            {
                stringCollection.Add(string.Format(
                    "{0},{1},{2},{3}",
                    col.DisplayIndex.ToString("D2"),
                    col.Width,
                    col.Visible,
                    i++));
            }
            Properties.Settings.Default.dvgHistoryFormColums = stringCollection;
            Properties.Settings.Default.Save();
        }

        private void toTopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (dgvQueue.SelectedCells.Count == 1)
            {
                int tmpindex = getIndexByNzo(dgvQueue.Rows[dgvQueue.SelectedCells[0].RowIndex].Cells["nzo_id"].Value.ToString());
                sabCom.queue.jobs[tmpindex].moveto(0);
                dgvqueue_forcerefresh = true;
            }
        }

        private void resumeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                sabCom.queue.resume();
            }
            catch { }
        }

        private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                sabCom.queue.pause();
            }
            catch { }
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            frmSettings set = new frmSettings(this);
            set.ShowDialog();
        }

        private void fileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dlr;

            dlr = ofdfFileAdd.ShowDialog();
            if (dlr != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }
            else
            {
                foreach (string f in ofdfFileAdd.FileNames)
                {
                    sabCom.queue.AddNzbFile(f);
                }
            }
        }

        private void tsbRemove_Click(object sender, EventArgs e)
        {
            if (dgvQueue.CurrentRow.Index != 0)
            {
                List<string> l = new List<string>();
                l.Add(dgvQueue.CurrentRow.Cells[10].Value.ToString());
                sabCom.queue.delete(l);
                //remove from jobs as well           
            }
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            frmAbout about;
            about = new frmAbout(this);
            about.ShowDialog();
        }

        private void shutdownToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            DialogResult dr;
            dr = MessageBox.Show("Are you sure you wish to shutdown the server?", "Shutdown", MessageBoxButtons.YesNo);
            if (dr == DialogResult.Yes)
            {
                sabCom.queue.shutdown();
            }
        }

        private void restartToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DialogResult dr;
            dr = MessageBox.Show("Are you sure you wish to restart the server?", "Restart", MessageBoxButtons.YesNo);
            if (dr == DialogResult.Yes)
            {
                sabCom.queue.restart();
            }
        }

        private void lstCats_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (dgvQueueFormatted == true)
            {
                if (lstCats.SelectedItem != null)
                {
                    if (lstCats.SelectedItem.ToString() == "*")
                    {
                        jobSource.DataSource = masterJobList;
                        queueIsFiltered = false;
                    }
                    else
                    {
                        try
                        {
                            BindingList<Job> filteredJobList = new BindingList<Job>(masterJobList.Where(m => m.category == lstCats.SelectedItem.ToString()).ToList());
                            jobSource.DataSource = filteredJobList;
                            queueIsFiltered = true;
                            curQueueFilter = lstCats.SelectedItem.ToString();
                        }
                        catch { }
                    }
                }
            }
        }

        private void lstCatsHistory_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (dgvHistoryFormatted == true)
            {
                if (lstCatsHistory.SelectedItem.ToString() == "*")
                {
                    historySource.DataSource = sabCom.history.jobs;
                    historyIsFiltered = false;
                }
                else
                {
                    try
                    {
                        BindingList<HistoryJob> filteredHistoryList = new BindingList<HistoryJob>(sabCom.history.jobs.Where(m => m.category == lstCatsHistory.SelectedItem.ToString()).ToList());
                        historySource.DataSource = filteredHistoryList;
                        historyIsFiltered = true;
                        curHistoryFilter = lstCatsHistory.SelectedItem.ToString();
                    }
                    catch { }
                }
            }
        }

        #endregion EventHandlers

        #region methods

        private void dgvQueue_Update()
        {
            masterJobList = new BindingList<Job>(sabCom.queue.jobs);
            if (!queueIsFiltered)
            {
                if (masterJobList.Count != dgvQueue.Rows.Count)
                {
                    jobSource.ResetBindings(false);
                    return;
                }
            }

            if (dgvqueue_forcerefresh == true)
            {
                jobSource.ResetBindings(false);
                dgvqueue_forcerefresh = false;
            }
            else
            {
                foreach (DataGridViewRow r in dgvQueue.Rows)
                {
                    dgvQueue.InvalidateRow(r.Index);
                }
            }
        }

        private void dgvQueue_Init()
        {
            try
            {
                masterJobList = new BindingList<Job>(sabCom.queue.jobs);
                jobSource.DataSource = masterJobList;
                dgvQueue.DataSource = jobSource;
                
                try
                {
                    dgvQueue_LoadDetails();
                }
                catch{}

                //Apply custom titles to fields.
                dgvQueue.Columns["priority"].HeaderText = "Priority";
                dgvQueue.Columns["timeleft"].HeaderText = "ETA";
                dgvQueue.Columns["age"].HeaderText = "Age";
                dgvQueue.Columns["mb"].HeaderText = "Size";
                dgvQueue.Columns["mbleft"].HeaderText = "Remaining";
                dgvQueue.Columns["status"].HeaderText = "Status";
                dgvQueue.Columns["category"].HeaderText = "Category";
                dgvQueue.Columns["percentage"].HeaderText = "Done";
                dgvQueue.Columns["nzo_id"].Visible = false;
                dgvQueueFormatted = true;

                //Change drawing styles to prevent flickering.
                typeof(DataGridView).InvokeMember(
                    "DoubleBuffered",
                    BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
                    null,
                    dgvQueue,
                    new object[] { true });
            }
            catch
            {
                //sabCom hasn't been init'd which means no valid connection.
            }
        }

        private void dqvQueue_headerContext_Init()
        {

            chkIndex.Text = "Index";
            chkIndex.BackColor = SystemColors.Control;
            ToolStripControlHost tschIndex = new ToolStripControlHost(chkIndex);
            tschIndex.BackColor = SystemColors.Control;
            chkIndex.CheckedChanged += new EventHandler(chkIndex_CheckedChanged);


            chkFilename.Text = "Filename";
            chkFilename.BackColor = SystemColors.Control;
            ToolStripControlHost tschFilename = new ToolStripControlHost(chkFilename);
            tschFilename.BackColor = SystemColors.Control;
            chkFilename.CheckedChanged += new EventHandler(chkFilename_CheckedChanged);


            chkPriority.Text = "Priority";
            chkPriority.BackColor = SystemColors.Control;
            ToolStripControlHost tschPriority = new ToolStripControlHost(chkPriority);
            tschPriority.BackColor = SystemColors.Control;
            chkPriority.CheckedChanged += new EventHandler(chkPriority_CheckedChanged);


            chkTimeLeft.Text = "Time Left";
            chkTimeLeft.BackColor = SystemColors.Control;
            ToolStripControlHost tschTimeLeft = new ToolStripControlHost(chkTimeLeft);
            tschTimeLeft.BackColor = SystemColors.Control;
            chkTimeLeft.CheckedChanged += new EventHandler(chkTimeLeft_CheckedChanged);


            chkAge.Text = "NZB Age";
            chkAge.BackColor = SystemColors.Control;
            ToolStripControlHost tschAge = new ToolStripControlHost(chkAge);
            tschAge.BackColor = SystemColors.Control;
            chkAge.CheckedChanged += new EventHandler(chkAge_CheckedChanged);


            chkMb.Text = "Total Size";
            chkMb.BackColor = SystemColors.Control;
            ToolStripControlHost tschMb = new ToolStripControlHost(chkMb);
            tschMb.BackColor = SystemColors.Control;
            chkMb.CheckedChanged += new EventHandler(chkMb_CheckedChanged);


            chkMbLeft.Text = "Size Remaining";
            chkMbLeft.BackColor = SystemColors.Control;
            ToolStripControlHost tschMbLeft = new ToolStripControlHost(chkMbLeft);
            tschMbLeft.BackColor = SystemColors.Control;
            chkMbLeft.CheckedChanged += new EventHandler(chkMbLeft_CheckedChanged);


            chkStatus.Text = "Status";
            chkStatus.BackColor = SystemColors.Control;
            ToolStripControlHost tschStatus = new ToolStripControlHost(chkStatus);
            tschStatus.BackColor = SystemColors.Control;
            chkStatus.CheckedChanged += new EventHandler(chkStatus_CheckedChanged);


            chkCategory.Text = "Category";
            chkCategory.BackColor = SystemColors.Control;
            ToolStripControlHost tschCategory = new ToolStripControlHost(chkCategory);
            tschCategory.BackColor = SystemColors.Control;
            chkCategory.CheckedChanged += new EventHandler(chkCategory_CheckedChanged);


            chkPercentage.Text = "Percent Complete";
            chkPercentage.BackColor = SystemColors.Control;
            ToolStripControlHost tschPercentage = new ToolStripControlHost(chkPercentage);
            tschPercentage.BackColor = SystemColors.Control;
            chkPercentage.CheckedChanged += new EventHandler(chkPercentage_CheckedChanged);


            chkNzoID.Text = "Nzo ID";
            chkNzoID.BackColor = SystemColors.Control;
            ToolStripControlHost tschNzoID = new ToolStripControlHost(chkNzoID);
            tschNzoID.BackColor = SystemColors.Control;
            chkNzoID.CheckedChanged += new EventHandler(chkNzoID_CheckedChanged);

            cmsColums.Items.Add(tschIndex);
            cmsColums.Items.Add(tschFilename);
            cmsColums.Items.Add(tschPriority);
            cmsColums.Items.Add(tschTimeLeft);
            cmsColums.Items.Add(tschAge);
            cmsColums.Items.Add(tschMb);
            cmsColums.Items.Add(tschMbLeft);
            cmsColums.Items.Add(tschStatus);
            cmsColums.Items.Add(tschCategory);
            cmsColums.Items.Add(tschPercentage);
            cmsColums.Items.Add(tschNzoID);
        }

        private void dgvQueue_SaveDetails()
        {
            StringCollection s = new StringCollection();
            string tName, tDIndex, tVisible, tWidth;
            foreach (DataGridViewColumn c in dgvQueue.Columns)
            {
                //to save: Name, DisplayIndex, Visible state, Width
                tName = c.Name;
                tDIndex = c.DisplayIndex.ToString();
                tVisible = c.Visible.ToString();
                tWidth = c.Width.ToString();
                string save = tName + "," + tDIndex + "," + tVisible + "," + tWidth;
                s.Add(save);
            }
            try
            {
                Properties.Settings.Default.dvgQueueFormColums.Clear();
            }
            catch { }
            Properties.Settings.Default.dvgQueueFormColums = s;
            Properties.Settings.Default.Save();
        }

        private void dgvQueue_LoadDetails()
        {
            StringCollection s = new StringCollection();
            string tName, tDIndex, tVisible, tWidth;
            foreach (string l in Properties.Settings.Default.dvgQueueFormColums)
            {
                string[] arr = l.Split(char.Parse(","));
                tName = arr[0];
                tDIndex = arr[1];
                tVisible = arr[2];
                tWidth = arr[3];
                dgvQueue.Columns[tName].DisplayIndex = int.Parse(tDIndex);
                dgvQueue.Columns[tName].Visible = bool.Parse(tVisible);
                dgvQueue.Columns[tName].Width = int.Parse(tWidth);
                switch (tName)
                {
                    case "Index":
                        chkIndex.Checked = bool.Parse(tVisible);
                        break;
                    case "Filename":
                        chkFilename.Checked = bool.Parse(tVisible);
                        break;
                    case "age":
                        chkAge.Checked = bool.Parse(tVisible);
                        break;
                    case "priority":
                        chkPriority.Checked = bool.Parse(tVisible);
                        break;
                    case "category":
                        chkCategory.Checked = bool.Parse(tVisible);
                        break;
                    case "timeleft":
                        chkTimeLeft.Checked = bool.Parse(tVisible);
                        break;
                    case "mb":
                        chkMb.Checked = bool.Parse(tVisible);
                        break;
                    case "mbleft":
                        chkMbLeft.Checked = bool.Parse(tVisible);
                        break;
                    case "nzo_id":
                        chkNzoID.Checked = bool.Parse(tVisible);
                        break;
                    case "percentage":
                        chkPercentage.Checked = bool.Parse(tVisible);
                        break;
                    case "status":
                        chkStatus.Checked = bool.Parse(tVisible);
                        break;
                }
            }
        }

        private void dgvHistory_Update()
        {
            masterHistoryList = new BindingList<HistoryJob>(sabCom.history.jobs);
            if (!historyIsFiltered)
            {
                if (masterHistoryList.Count != dgvHistory.Rows.Count)
                {
                    historySource.ResetBindings(false);
                    return;
                }

            }
            foreach (DataGridViewRow r in dgvHistory.Rows)
            {
                dgvHistory.InvalidateRow(r.Index);
            }
        }

        private void dgvHistory_Init()
        {
            try
            {
                historySource.DataSource = sabCom.history.jobs;
                dgvHistory.DataSource = historySource;
                try
                {
                    dgvHistory_LoadDetails();
                }
                catch{}

                //Apply custom titles to fields.
                dgvHistory.Columns["action_line"].HeaderText = "Action Line";
                dgvHistory.Columns["id"].HeaderText = "ID";
                dgvHistory.Columns["size_byte"].HeaderText = "Bytes";
                dgvHistory.Columns["category"].HeaderText = "Category";
                dgvHistory.Columns["nzb_name"].HeaderText = "NZB Name";
                dgvHistory.Columns["download_time"].HeaderText = "Download Time";
                dgvHistory.Columns["path"].HeaderText = "Path";
                dgvHistory.Columns["postproc_time"].HeaderText = "PostProc Time";
                dgvHistory.Columns["name"].HeaderText = "Job Name";
                dgvHistory.Columns["url"].HeaderText = "Nzb URL";
                dgvHistory.Columns["url_info"].HeaderText = "Info URL";
                dgvHistoryFormatted = true;

                //Change drawing styles to prevent flickering.
                typeof(DataGridView).InvokeMember(
                    "DoubleBuffered",
                    BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
                    null,
                    dgvHistory,
                    new object[] { true });
            }
            catch
            {
                //sabCom hasn't been init'd which means no valid connection.
            }
        }
        
        private void dgvHistory_headerContext_Init()
        {

            chkhID.Text = "Id";
            chkhID.BackColor = SystemColors.Control;
            ToolStripControlHost tschID = new ToolStripControlHost(chkhID);
            tschID.BackColor = SystemColors.Control;
            chkhID.CheckedChanged += new EventHandler(chkhID_CheckedChanged);


            chkhName.Text = "Job Name";
            chkhName.BackColor = SystemColors.Control;
            ToolStripControlHost tschName = new ToolStripControlHost(chkhName);
            tschName.BackColor = SystemColors.Control;
            chkhName.CheckedChanged += new EventHandler(chkhName_CheckedChanged);


            chkhSizeBytes.Text = "Size (bytes)";
            chkhSizeBytes.BackColor = SystemColors.Control;
            ToolStripControlHost tschSizeBytes = new ToolStripControlHost(chkhSizeBytes);
            tschSizeBytes.BackColor = SystemColors.Control;
            chkhSizeBytes.CheckedChanged += new EventHandler(chkhSizeBytes_CheckedChanged);


            chkhCategory.Text = "Category";
            chkhCategory.BackColor = SystemColors.Control;
            ToolStripControlHost tschTimeLeft = new ToolStripControlHost(chkhCategory);
            tschTimeLeft.BackColor = SystemColors.Control;
            chkhCategory.CheckedChanged += new EventHandler(chkhCategory_CheckedChanged);


            chkhDownloadTime.Text = "Download Time";
            chkhDownloadTime.BackColor = SystemColors.Control;
            ToolStripControlHost tschDownloadTime = new ToolStripControlHost(chkhDownloadTime);
            tschDownloadTime.BackColor = SystemColors.Control;
            chkhDownloadTime.CheckedChanged += new EventHandler(chkhDownloadTime_CheckedChanged);


            chkhPath.Text = "File Path";
            chkhPath.BackColor = SystemColors.Control;
            ToolStripControlHost tschPath = new ToolStripControlHost(chkhPath);
            tschPath.BackColor = SystemColors.Control;
            chkhPath.CheckedChanged += new EventHandler(chkhPath_CheckedChanged);


            chkhPostprocTime.Text = "PostProc Time";
            chkhPostprocTime.BackColor = SystemColors.Control;
            ToolStripControlHost tschPostprocTime = new ToolStripControlHost(chkhPostprocTime);
            tschPostprocTime.BackColor = SystemColors.Control;
            chkhPostprocTime.CheckedChanged += new EventHandler(chkhPostprocTime_CheckedChanged);


            chkhUrl.Text = "URL";
            chkhUrl.BackColor = SystemColors.Control;
            ToolStripControlHost tschURL = new ToolStripControlHost(chkhUrl);
            tschURL.BackColor = SystemColors.Control;
            chkhUrl.CheckedChanged += new EventHandler(chkhUrl_CheckedChanged);


            chkhUrlInfo.Text = "URL Info";
            chkhUrlInfo.BackColor = SystemColors.Control;
            ToolStripControlHost tschUrlInfo = new ToolStripControlHost(chkhUrlInfo);
            tschUrlInfo.BackColor = SystemColors.Control;
            chkhUrlInfo.CheckedChanged += new EventHandler(chkhUrlInfo_CheckedChanged);


            chkhActionLine.Text = "Action Line";
            chkhActionLine.BackColor = SystemColors.Control;
            ToolStripControlHost tschActionLine = new ToolStripControlHost(chkhActionLine);
            tschActionLine.BackColor = SystemColors.Control;
            chkhActionLine.CheckedChanged += new EventHandler(chkhActionLine_CheckedChanged);


            chkhNzbNam.Text = "NZB Name";
            chkhNzbNam.BackColor = SystemColors.Control;
            ToolStripControlHost tschNzoName = new ToolStripControlHost(chkhNzbNam);
            tschNzoName.BackColor = SystemColors.Control;
            chkhNzbNam.CheckedChanged += new EventHandler(chkhNzbNam_CheckedChanged);

            cmsHistoryColums.Items.Add(tschID);
            cmsHistoryColums.Items.Add(tschName);
            cmsHistoryColums.Items.Add(tschSizeBytes);
            cmsHistoryColums.Items.Add(tschTimeLeft);
            cmsHistoryColums.Items.Add(tschDownloadTime);
            cmsHistoryColums.Items.Add(tschPath);
            cmsHistoryColums.Items.Add(tschPostprocTime);
            cmsHistoryColums.Items.Add(tschURL);
            cmsHistoryColums.Items.Add(tschUrlInfo);
            cmsHistoryColums.Items.Add(tschActionLine);
            cmsHistoryColums.Items.Add(tschNzoName);
        }
        
        private void dgvHistory_SaveDetails()
        {
            StringCollection s = new StringCollection();
            string tName, tDIndex, tVisible, tWidth;
            foreach (DataGridViewColumn c in dgvHistory.Columns)
            {
                //to save: Name, DisplayIndex, Visible state, Width
                tName = c.Name;
                tDIndex = c.DisplayIndex.ToString();
                tVisible = c.Visible.ToString();
                tWidth = c.Width.ToString();
                string save = tName + "," + tDIndex + "," + tVisible + "," + tWidth;
                s.Add(save);
            }
            try { Properties.Settings.Default.dvgHistoryFormColums.Clear(); }
            catch { }
            Properties.Settings.Default.dvgHistoryFormColums = s;
            Properties.Settings.Default.Save();
        }

        private void dgvHistory_LoadDetails()
        {
            StringCollection s = new StringCollection();
            string tName, tDIndex, tVisible, tWidth;
            foreach (string l in Properties.Settings.Default.dvgHistoryFormColums)
            {
                string[] arr = l.Split(char.Parse(","));
                tName = arr[0];
                tDIndex = arr[1];
                tVisible = arr[2];
                tWidth = arr[3];
                dgvHistory.Columns[tName].DisplayIndex = int.Parse(tDIndex);
                dgvHistory.Columns[tName].Visible = bool.Parse(tVisible);
                dgvHistory.Columns[tName].Width = int.Parse(tWidth);
                switch (tName)
                {
                    case "id":
                        chkhID.Checked = bool.Parse(tVisible);
                        break;
                    case "name":
                        chkhName.Checked = bool.Parse(tVisible);
                        break;
                    case "size_byte":
                        chkhSizeBytes.Checked = bool.Parse(tVisible);
                        break;
                    case "category":
                        chkhCategory.Checked = bool.Parse(tVisible);
                        break;
                    case "download_time":
                        chkhDownloadTime.Checked = bool.Parse(tVisible);
                        break;
                    case "path":
                        chkhPath.Checked = bool.Parse(tVisible);
                        break;
                    case "postproc_time":
                        chkhPostprocTime.Checked = bool.Parse(tVisible);
                        break;
                    case "url":
                        chkhUrl.Checked = bool.Parse(tVisible);
                        break;
                    case "url_info":
                        chkhUrlInfo.Checked = bool.Parse(tVisible);
                        break;
                    case "action_line":
                        chkhActionLine.Checked = bool.Parse(tVisible);
                        break;
                    case "nzb_name":
                        chkhNzbNam.Checked = bool.Parse(tVisible);
                        break;
                }
            }
        }

        private void ssStatus_Update()
        {
            switch (sabCom.queue.status)
            {
                case "Downloading":
                    resumeToolStripMenuItem.Visible = false;
                    pauseToolStripMenuItem.Visible = true;
                    ddbStatus.Image = Properties.Resources.down;
                    tslStatus.Text = "Downloading.";
                    ddbStatus.ToolTipText = "Downloading.";
                    break;
                case "Paused":
                    resumeToolStripMenuItem.Visible = true;
                    pauseToolStripMenuItem.Visible = false;
                    ddbStatus.Image = Properties.Resources.pause;
                    tslStatus.Text = "Paused.";
                    ddbStatus.ToolTipText = "Paused.";
                    break;
                case "Idle":
                    resumeToolStripMenuItem.Visible = false;
                    pauseToolStripMenuItem.Visible = true;
                    ddbStatus.Image = Properties.Resources.exclamation;
                    tslStatus.Text = "Idle.";
                    ddbStatus.ToolTipText = "Idle.";
                    break;
            }
            tssbSpeedLimit.Text = sabCom.queue.transferRate.ToString() + "kb/s";
            tslFreeSpace1.Text = formatSize(sabCom.queue.diskspace1);
            tslFreeSpace2.Text = formatSize(sabCom.queue.diskspace2);
        }

        private void lstviewCat_Init()
        {
            lstCats.Items.Add("*");
            lstCatsHistory.Items.Add("*");
            foreach (string s in sabCom.queue.categories)
            {
                lstCats.Items.Add(s);
                lstCatsHistory.Items.Add(s);
            }

            typeof(ListBox).InvokeMember(
                       "DoubleBuffered",
                       BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
                       null,
                       lstCats,
                       new object[] { true });
            typeof(ListBox).InvokeMember(
                       "DoubleBuffered",
                       BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
                       null,
                       lstCatsHistory,
                       new object[] { true });
        }

        #endregion methods

        #region functions

        private string formatSize(double gbsize)
        {
            string retval;
            if (gbsize < 1024)
            {
                gbsize = Math.Round(gbsize, 2);
                retval = gbsize.ToString() + "GB";
            }
            else
            {
                double tmp;
                tmp = gbsize / 1024;
                tmp = Math.Round(tmp, 2);
                retval = tmp.ToString() + "TB";
            }
            return retval;
        }

        private int getIndexByNzo(string nzo_id)
        {
            foreach (Job r in sabCom.queue.jobs)
            {
                if (r.nzo_id == nzo_id)
                {
                    return r.Index;
                }
            }
            return -1;
        }

        private Job getJobByNzo(string nzo)
        {
            foreach (Job j in sabCom.queue.jobs)
            {
                if (j.nzo_id == nzo)
                {
                    return j;
                }
            }
            return new Job("", 0, "", new TimeSpan(), "", 0, 0, "", Job.Priority.Default, "", 0, "", sabCom.queue);
        }

        private HistoryJob getHistoryJobById(int id)
        {
            foreach (HistoryJob j in sabCom.history.jobs)
            {
                if (j.id == id)
                {
                    return j;
                }
            }
            return new HistoryJob("", 0, 0, "", "", 0, "", 0, "", "", "", new StageLog());
        }

        #endregion functions

        private void exitClientToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void frmMain_DragDrop(object sender, DragEventArgs e)
        {
            int i = 0;
        }

        private void dgvQueue_DragDrop(object sender, DragEventArgs e)
        {
            int i = 0;
        }


    }
}
